package com.ruoyi.business.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.SaveType;
import com.ruoyi.common.utils.EncrypDES;
import com.ruoyi.common.utils.GetUrlParam;
import com.ruoyi.common.utils.OtherUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.system.domain.vo.R;
import com.ruoyi.system.protocol.IDynamicDataService;
import com.ruoyi.system.protocol.IDynamicSearchService;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("ownApi")
public class IndexController {

    @Autowired
    private IDynamicSearchService dynamicSearchService;

    @Autowired
    private RedisCache redisCache;

    private final static String CLASSESEN = "advertising_space";



    @Log(title = "之行传媒SSP", businessType = BusinessType.ESCALATION, esIndex = "zhixing_log", saveType = SaveType.ES)
    @RequestMapping("/send")
    public R send(HttpServletRequest request) throws Exception {
        String queryString = request.getQueryString();
        String channelId = request.getParameter("channelId");
        String dmpid = request.getParameter("dmpid");
        if(StringUtils.isBlank(channelId)){
            return R.failure().msg("channelId不能为空");
        }
        if(StringUtils.isBlank(dmpid)){
            return R.failure().msg("dmpid不能为空");
        }
        List<String> queryStringList = new ArrayList<>(Arrays.asList(queryString.split("&")));
        queryStringList.remove("channelId="+channelId);
//        queryStringList.remove("mki="+mki);

        //数据库查询需要优化， 现在需要 139ms 耗时太高
//        Map<String, Object> channelDetail = dynamicDataService.findDynamicData("advertising_space", null, channelId);
        Map<String, Object> channelDetail = redisCache.getCacheMapValue(CLASSESEN+"Cache", channelId);
        if(channelDetail == null){
            return R.failure().msg("channelId不正确");
        }
        if("0".equals(channelDetail.get("isopen")+"")){
            return R.failure().msg("channelId未开启");
        }
        String url = channelDetail.get("request_address") + "";
        String requestType = channelDetail.get("request_type") + "";
        String requestAddress = GetUrlParam.getRequestAddress(url);
        String staticParameters = GetUrlParam.TruncateUrlPage(url);
        Map<String, Object> paramsMap = GetUrlParam.queryStrToMap(queryString);
        queryStringList.add(staticParameters);
        String requestParameters = String.join("&", queryStringList);
        String reportResultsStr = "";
        String ua = paramsMap.get("ua") + "";
        String ip = paramsMap.get("i") + "";
        if(StringUtils.isNotBlank(ua) && !"null".equals(ua)){
            ua = URLDecoder.decode(ua, Constants.UTF8);
        }else{
            ua = null;
        }
        if(StringUtils.isNotBlank(ip) && !"null".equals(ip)){
        }else{
            ip = null;
        }
        if("POST".equals(requestType)){
            reportResultsStr = HttpUtils.sendPost(requestAddress, requestParameters, ip, ua);
        }else{
            reportResultsStr = HttpUtils.sendGet(requestAddress, requestParameters, ip, ua);
        }

        JSONObject reportResults = JSONObject.parseObject(reportResultsStr);
        if(reportResults.getInteger("status") != 0){
            return R.failure().code(reportResults.getInteger("status")+"").msg(reportResults.getString("error_msg"));
        }

        EncrypDES encrypDES = new EncrypDES();

        String callbackBase = OtherUtils.getServerUrl(request) + "ownApi/callback/"+channelId+"/"+dmpid+"/";
        JSONArray ads = reportResults.getJSONArray("ads");
        for (Object o : ads) {
            JSONObject jsonObject = (JSONObject)o;
            JSONArray cm = jsonObject.getJSONArray("cm");
            JSONArray ncm = new JSONArray();
            for (Object o1 : cm) {
                String u = o1 + "";
                String ub = GetUrlParam.getRequestAddress(u);
                String sp = GetUrlParam.TruncateUrlPage(u);
                String encrypt_u = encrypDES.encrypt(ub);
                String nu = callbackBase + encrypt_u;
                if(StringUtils.isNotBlank(sp)){
                    nu += "?" + sp;
                }
                ncm.add(nu);
            }
            jsonObject.put("cm", ncm);

            JSONArray pm = jsonObject.getJSONArray("pm");
            JSONArray npm = new JSONArray();
            for (Object o1 : pm) {
                String u = o1 + "";
                String ub = GetUrlParam.getRequestAddress(u);
                String sp = GetUrlParam.TruncateUrlPage(u);
                String encrypt_u = encrypDES.encrypt(ub);
                String nu = callbackBase + encrypt_u;
                if(StringUtils.isNotBlank(sp)){
                    nu += "?" + sp;
                }
                npm.add(nu);
            }
            jsonObject.put("pm", npm);


            JSONObject em = jsonObject.getJSONObject("em");
            JSONObject nem = new JSONObject();
            for(String key: em.keySet()){
                JSONArray j = em.getJSONArray(key);
                JSONArray nj = new JSONArray();
                for (Object o1 : j) {
                    String u = o1 + "";
                    String ub = GetUrlParam.getRequestAddress(u);
                    String sp = GetUrlParam.TruncateUrlPage(u);
                    String encrypt_u = encrypDES.encrypt(ub);
                    String nu = callbackBase + encrypt_u;
                    if(StringUtils.isNotBlank(sp)){
                        nu += "?" + sp;
                    }
                    nj.add(nu);
                }
                nem.put(key, nj);
            }
            jsonObject.put("em", nem);
        }

       return R.success().code(reportResults.getInteger("status")+"")
               .data("ads", reportResults.getJSONArray("ads"))
               .data("dmpid", dmpid)
               .data("preload", reportResults.getJSONArray("preload"))
               .data("current", reportResults.getString("current"));
    }


    @Log(title = "之行传媒SSP", businessType = BusinessType.CALLBACK, esIndex = "zhixing_log", saveType = SaveType.ES)
    @RequestMapping("/callback/{channelId}/{dmpid}/{encryptedUrl}")
    public R send(HttpServletRequest request, @PathVariable("encryptedUrl") String encryptedUrl) throws Exception {
        String queryString = request.getQueryString();
        EncrypDES encrypDES = new EncrypDES();
        String requestAddress = encrypDES.decrypt(encryptedUrl);
        String resultStr = HttpUtils.sendGet(requestAddress, queryString);
        return R.success().data("resultStr", resultStr);
    }

}
